#!/usr/bin/env python
#coding=utf-8
'''
Created on Aug 19, 2010
@author: lxd
'''
from web_qq7x import QQ7xWeb
import tools
import parse
from pyamf.remoting.client import RemotingService
import pyamf
from pyamf.remoting import RemotingError
import time

class QQ7X():
    def __init__(self, user, pwd, serverId):
        self.user = user
        self.pwd = pwd
        self.serverId = serverId  
              
        self.log = tools.log
        self.web = QQ7xWeb(self.log)
        self.cookies_map = {}#验证的关键
        
    def __getVerifyCode(self, f):
        code = f.read()#保存验证码
        f = open('code.jpg', 'wb')
        f.write(code)
        f.close()   
        
        import os
        os.system('code.jpg') #打开图片  
        
    def getVerityCode(self):
        f = self.web.getVerifyCode()
        self.__getVerifyCode(f) 
        verifyCode = raw_input(u'请输入验证码:').upper() 
        return verifyCode  
        
    def login(self, user, password, verifyCode):     
        self.web.login(user, password, verifyCode)#登陆
        cookies = self.web.cookies#get login cookies
        cookie_map = tools.cookieObjToMap(cookies)
        self.cookies_map.update(cookie_map)
        
    def loginApp(self):                
        self.web.loginApp(self.serverId)
        cookies = self.web.cookies#get _fx_login
        cookie_map = tools.cookieObjToMap(cookies)
        self.cookies_map.update(cookie_map)
    
    def loginGame(self):
        url = 'http://s%s.jn2.7.qq.com/dynasty/swf/login.jhtml?cdnUrl=cdn.dl.7.qq.com&PcacheTime=1282569039' % serverId
        referer = 'http://commwebgame.qq.com/cgi-bin/CommWebGame/7X/7XLoginApp.cgi'
        cookies_str = tools.cookieMapToStr(self.cookies_map)
        response, content = tools.httpNoRedirectKeepAlive(url, referer, cookies_str)
        cookie_str = response.get('set-cookie', '') 
        cookie_map = tools.cookieStrToMap(cookie_str)
        self.cookies_map.update(cookie_map)        
                
    def getCookie(self):
        verifyCode = self.getVerityCode()
        password = parse.getP(self.pwd, verifyCode)    
        self.login(self.user, password, verifyCode)
        self.loginApp()
        self.loginGame()
        cookies_str = tools.cookieMapToStr(self.cookies_map) 
        return cookies_str  
    
    def getAMFClient(self, cookies):
        gateway = 'http://s%s.jn2.7.qq.com/dynasty/messagebroker/amf' % self.serverId
        referer = 'http://cdn.dl.7.qq.com/dynasty/swf/Loading.swf?7b7df3a0b1466fdd47005e9cbce61cde'
                
        pyamf.remoting.CONTENT_TYPE = 'application/x-amf;charset=UTF-8'
        user_agent = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3'

        client = RemotingService(gateway, amf_version=pyamf.AMF3, logger=self.log, user_agent=user_agent, referer=referer)
        client.http_headers = {
                            'cookie':cookies,
                            'Connection':'keep-alive', #not need indeed
                            'Keep-Alive':115,
                            'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                            'Accept-Language':'en-us,en;q=0.5',
                            'Accept-Encoding':'gzip,deflate',
                            'Accept-Charset':'x-gbk,utf-8;q=0.7,*;q=0.7',
                             }
        return client

    def postData(self, serviceName, funName, *args):
        result = None
        service = self.client.getService(serviceName)
        if args:
            data = []
            for arg in args:    
                data.append(tools.amfData(tools.encode(arg)))
            try:
                result = getattr(service, funName)(*data) 
            except RemotingError, err:
                self.log.error((RemotingError, err))
                raise RemotingError
        else:
            try:
                result = getattr(service, funName)() 
            except RemotingError, err:
                self.log.error((RemotingError, err))
                raise RemotingError
        return result   
    
    def enterGame(self):
        cookies = self.getCookie()
        self.client = self.getAMFClient(cookies)
        
        data = self.postData('accountAct', 'getCryptKey')
        key = data['key']
        num = data['num']
        self.log.info('key:%s;num:%s' % (key, num))
        #key:4784e4708d99d915d39ddf933497bbad;num:3
        
        if self.postData('accountAct', 'isEnterGame') == 0:
            self.log.info('enter game success')
        else:
            self.log.info('enter game failure')
            exit()
            
#        self.log.info(self.postData('accountAct', 'getCryptKey'))
        data = self.postData('accountAct', 'enterGame')
        self.log.info(parse.enterGame(data).__dict__)
        
        data = self.postData('accountAct', 'getUserCastles')
        r = parse.getUserCastles(data)
        if r:
            casId = r.casId
        else:
            casId = None    
            self.log.error('cannot get casId')
            
        #"chatAct.reg"
        #[[50, 5, 97, 85]]
        
#        self.log.info(self.postData('shopAct', 'getCountryList'))
        
        if casId:
            data = self.postData('castleAct', 'listCastleBuilding', casId)
            self.buildings = parse.listCastleBuilding(data)
                
#        "castleAct.getBuffTipListById"
#        [[48, 130, 191, 103]]
#        
#        "assistantAct.getAllEventWindowList"
#        
#        "accountAct.refreshUserDailyInfo"
#        
#        "castleAct.freshCastleData"
#        [[48, 130, 191, 103]]
#        
#        "onlineAwardAct.getOnlineTimeAward"
#        
#        "userAct.getLoginActivity"
#        
#        "personAct.getLuckInfo"
#        
#        "accountAct.sendFCMMsg"
#        
#        "accountAct.getSynData"
#        
#        "chatAct.receiveAllMessage"
#        [[50, 3, 49]]
#        
#        "personAct.getAllPerson"
#        [[48, 130, 191, 103]]
#        
#        "castleAct.getCastleResAndPop"
#        
#        "castleAct.getBuffTipListById"
#        [[48, 130, 191, 103]]
#        
#        "userAct.getDailyGiftView"
#        
#        "accountAct.getTreasurySynInitData"
#        
#        "personAct.getLuckPerson"
#        [[48, 130, 191, 103]]
#        
#        "userFarmAct.enterFarmExt"
#        [[48, 130, 190, 125]]
#        
#        "dailyMissionAct.getUserDailyMissionList"
#        
#        "missionAct.showUserMissionByType"
#        [[50, 21, 81, 96, 89, 80, 114, 95, 77, 37, 73, 78]]
#        
#        "castleAct.getSynUserTech"
    def farm(self):   
        self.log.info(self.postData('userFarmAct', 'getFriendInfo', 1, 2))
        
    def getBuilds(self):
        #按等级从低到高自动列出升级顺序10个
        import copy 
        builds = [b for b in self.buildings if b.isBuilding == -1]   #不是正在建造的      
        lst = []
        for i in range(10):
            builds = sorted(builds, key=lambda x:x.level)
            leastBuild = copy.deepcopy(builds[0])
            lst.append(leastBuild)
            builds[0].level = leastBuild.level + 1
        return lst
                
    def building(self):
        
#        "castleAct.selectCasBui"
#        [[48, 130, 191, 103], [50, 7, 67, 5,48]]
        if self.buildings:
            for build in self.buildings:
                self.log.info((build.casBuiId, build.buiName, build.level, build.posNo, build.isBuilding, build.casId))
                
   
            builds = self.getBuilds()
#            for build in builds:
            build = builds[0]
            
            self.log.info(self.postData('castleAct', 'levelUpCastleBui', build.casBuiId))
            
            data = self.postData('castleAct', 'refreshCasBui', build.casId, build.posNo)  
            remainTime = parse.refreshCasBui(data).isBuilding
            self.log.info('%sS left' % remainTime)
            
            time.sleep(3)         
                 
            data = self.postData('castleAct', 'refreshCasBui', build.casId, build.posNo)  
            remainTime = parse.refreshCasBui(data).isBuilding
            self.log.info('%sS left' % remainTime) 
              
        else:
            self.log.error('cannot get buildings')
        
          
if __name__ == '__main__':
#    user = '389009498'
#    pwd = '108352456cyh'
#    serverId = 605
    
    user = '375313961'
    pwd = '86057043lxdcyh'
    serverId = 610
    qq = QQ7X(user, pwd, serverId)        
    qq.enterGame()
    qq.building()     
    print 'over'

    
